package lighthouse.threading;
import com.google.common.collect.ImmutableList;
import javafx.collections.FXCollections;
import javafx.collections.ListChangeListener;
import javafx.collections.ObservableList;
import javafx.collections.ObservableSet;
import org.junit.Before;
import org.junit.Test;
import java.util.LinkedList;
import java.util.Queue;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
public class ObservableMirrorsTest {
private AffinityExecutor.Gate gate;
@Before
public void setup() {
gate = new AffinityExecutor.Gate(true);
}
@Test
public void mirroredSet() throws Exception {
ObservableSet<String> source = FXCollections.observableSet();
source.add("alpha");
source.add("beta");
ObservableSet<String> dest = ObservableMirrors.mirrorSet(source, gate);
assertEquals(0, gate.getTaskQueueSize());
assertEquals(2, dest.size());
source.add("delta");
assertEquals(1, gate.getTaskQueueSize());
assertEquals(2, dest.size());
gate.waitAndRun();
assertEquals(0, gate.getTaskQueueSize());
assertEquals(3, dest.size());
source.removeAll(ImmutableList.of("alpha", "beta"));
assertEquals(2, gate.getTaskQueueSize());
gate.waitAndRun();
gate.waitAndRun();
assertEquals(1, dest.size());
assertTrue(dest.contains("delta"));
}
@Test
public void observableList() throws Exception {
ObservableList<String> source = FXCollections.observableArrayList();
source.addAll("alpha", "beta");
ObservableList<String> dest = ObservableMirrors.mirrorList(source, gate);
Queue<ListChangeListener.Change<? extends String>> changes = new LinkedList<>();
dest.addListener(changes::add);
// Expect a single change with two added items.
source.addAll("gamma", "delta");
assertEquals(1, gate.getTaskQueueSize());
gate.waitAndRun();
ListChangeListener.Change<? extends String> change = changes.poll();
change.next();
assertTrue(change.wasAdded());
assertEquals(2, change.getAddedSize());
assertEquals(ImmutableList.of("gamma", "delta"), change.getAddedSubList());
// Expect four queued changes with coherent/correct deltas unaffected by later changes to the src list.
source.remove(3); // remove delta
source.add("phi");
source.remove(3); // remove phi
source.add("epsilon");
assertEquals(4, gate.getTaskQueueSize());
gate.waitAndRun();
gate.waitAndRun();
change = changes.poll();
change.next();
assertTrue(change.wasRemoved());
assertEquals(1, change.getRemovedSize());
assertEquals("delta", change.getRemoved().get(0));
change = changes.poll();
change.next();
assertTrue(change.wasAdded());
assertEquals("phi", change.getAddedSubList().get(0));
gate.waitAndRun();
changes.poll();
gate.waitAndRun();
changes.poll();
// Expect a set on the source list to show up as a replace event on the dest list.
source.set(0, "zero");
gate.waitAndRun();
change = changes.poll();
change.next();
assertTrue(change.toString(), change.wasReplaced());
assertEquals(0, change.getFrom());
assertEquals(1, change.getTo());
assertEquals("zero", change.getAddedSubList().get(0));
}
}